home *** CD-ROM | disk | FTP | other *** search
- {
- > Does anybody know if it is possible to accomplish a smooth-text scroller
- > (like in the old c64 dayz) in text mode? If so, please let me know and
-
- > Well, it's impossible, you'll have to switch to a graphic mode.
-
- No, it's possible in text mode... it's just a pain in the
- arse. I know of two ways. The first is to use an alternate
- character set (the EGA can have 2 on screen at once, the VGA can
- have 4). You use one character set as normal text, and use the
- other as a pseudo-graphics window. Put the text you need to
- scroll in the window and move (copy) it a pixel at a time. The
- second way is to use the 8253 timer to time the scanline. When
- the scanline gets to the portion of the screen you want, turn off
- v-retrace, set v-retrace on the next scan line, and set the
- horizontal pel pan to the value you need for your smooth pan.
- When the card gets to the line that the v-retrace would occur, it
- resets the pan but doesn't retrace because you turned it off.
- After this, reset the registers you changed back to their default
- values so the card builds the screen correctly. This is done on
- EVERY screen build. Needless to say, the pseudo-graphics window
- version is easier so that's the one I used to program the example
- that follows.
- }
-
- Program SmoothTextScrollExample1;
-
- {==============================================
-
- Smooth Scroll In Text Mode Example
- Programmed by David Dahl
- 12/21/93
- This program and source are PUBLIC DOMAIN
-
- ----------------------------------------------
-
- This example uses a second font to scroll
- the text. The font definition is changed
- to make the text scroll. This program
- requires VGA.
-
- ==============================================}
-
- Uses CRT;
-
- Type FontDefType = Array[0..255, 0..31] of Byte;
-
- Var ScrollText : String;
-
- FontDef : FontDefType;
-
- Procedure SetCharWidthTo8; Assembler;
- Asm
- { Change To 640 Horz Res }
- MOV DX, $3CC
- IN AL, DX
- AND AL, Not(4 OR 8)
- MOV DX, $3C2
- OUT DX, AL
-
- { Turn Off Sequence Controller }
- MOV DX, $3C4
- MOV AL, 0
- OUT DX, AL
- MOV DX, $3C5
- MOV AL, 0
- OUT DX, AL
-
- { Reset Sequence Controller }
- MOV DX, $3C4
- MOV AL, 0
- OUT DX, AL
- MOV DX, $3C5
- MOV AL, 3
- OUT DX, AL
-
- { Switch To 8 Pixel Wide Fonts }
- MOV DX, $3C4
- MOV AL, 1
- OUT DX, AL
- MOV DX, $3C5
- IN AL, DX
- OR AL, 1
- OUT DX, AL
-
- { Turn Off Sequence Controller }
- MOV DX, $3C4
- MOV AL, 0
- OUT DX, AL
- MOV DX, $3C5
- MOV AL, 0
- OUT DX, AL
-
- { Reset Sequence Controller }
- MOV DX, $3C4
- MOV AL, 0
- OUT DX, AL
- MOV DX, $3C5
- MOV AL, 3
- OUT DX, AL
-
- { Center Screen }
- MOV DX, $3DA
- IN AL, DX
- MOV DX, $3C0
- MOV AL, $13 OR 32
- OUT DX, AL
- MOV AL, 0
- OUT DX, AL
- End;
-
- Procedure WriteScrollTextCharacters(Row : Byte);
- Var Counter : Word;
- Begin
- { Set Fonts 0 & 1 }
- ASM
- MOV BL, 4
- MOV AX, $1103
- INT $10
- END;
-
- { Write Characters }
- For Counter := 0 to 79 do
- Begin
- { Set Characters }
-
- MEM[$B800:(80*2)*Row+(Counter*2)] := Counter;
- { Set Attribute To Secondary Font }
- MEM[$B800:(80*2)*Row+(Counter*2)+1] :=
- MEM[$B800:(80*2)*Row+(Counter*2)+1] OR 8;
-
- End;
-
- End;
-
- Procedure FlushKeyBoardBuffer;
- Var Key : Char;
- Begin
- While KeyPressed do
- Key := ReadKey;
- End;
-
- Procedure SetAccessToFontMemory; Assembler;
- ASM
- { Turn Off Sequence Controller }
- MOV DX, $3C4
- MOV AL, 0
- OUT DX, AL
- MOV DX, $3C5
- MOV AL, 1
- OUT DX, AL
-
- { Reset Sequence Controller }
- MOV DX, $3C4
- MOV AL, 0
- OUT DX, AL
- MOV DX, $3C5
- MOV AL, 3
- OUT DX, AL
-
- { Change From Odd/Even Addressing to Linear }
- MOV DX, $3C4
- MOV AL, 4
- OUT DX, AL
- MOV DX, $3C5
- MOV AL, 7
- OUT DX, AL
-
- { Switch Write Access To Plane 2 }
- MOV DX, $3C4
- MOV AL, 2
- OUT DX, AL
- MOV DX, $3C5
- MOV AL, 4
- OUT DX, AL
-
- { Set Read Map Reg To Plane 2 }
- MOV DX, $3CE
- MOV AL, 4
- OUT DX, AL
- MOV DX, $3CF
- MOV AL, 2
- OUT DX, AL
-
- { Set Graphics Mode Reg }
- MOV DX, $3CE
- MOV AL, 5
- OUT DX, AL
- MOV DX, $3CF
- MOV AL, 0
- OUT DX, AL
-
- { Set Misc. Reg }
- MOV DX, $3CE
- MOV AL, 6
- OUT DX, AL
- MOV DX, $3CF
- MOV AL, 12
- OUT DX, AL
- End;
-
- Procedure SetAccessToTextMemory; Assembler;
- ASM
- { Turn Off Sequence Controller }
- MOV DX, $3C4
- MOV AL, 0
- OUT DX, AL
- MOV DX, $3C5
- MOV AL, 1
- OUT DX, AL
-
- { Reset Sequence Controller }
- MOV DX, $3C4
- MOV AL, 0
- OUT DX, AL
- MOV DX, $3C5
- MOV AL, 3
- OUT DX, AL
-
- { Change To Odd/Even Addressing }
- MOV DX, $3C4
- MOV AL, 4
- OUT DX, AL
- MOV DX, $3C5
- MOV AL, 3
- OUT DX, AL
-
- { Switch Write Access }
- MOV DX, $3C4
- MOV AL, 2
- OUT DX, AL
- MOV DX, $3C5
- MOV AL, 3 {?}
- OUT DX, AL
-
- { Set Read Map Reg }
- MOV DX, $3CE
- MOV AL, 4
- OUT DX, AL
- MOV DX, $3CF
- MOV AL, 0
- OUT DX, AL
-
- { Set Graphics Mode Reg }
- MOV DX, $3CE
- MOV AL, 5
- OUT DX, AL
- MOV DX, $3CF
- MOV AL, $10
- OUT DX, AL
-
- { Set Misc. Reg }
- MOV DX, $3CE
- MOV AL, 6
- OUT DX, AL
- MOV DX, $3CF
- MOV AL, 14
- OUT DX, AL
- End;
-
- Procedure MakeFontDefTable;
- Var CounterX,
- CounterY : Word;
- Begin
- SetAccessToFontMemory;
-
- For CounterY := 0 to 255 do
- For CounterX := 0 to 31 do
- FontDef[CounterY, CounterX] :=
- MEM[$B800:(CounterY * 32)+CounterX];
-
- SetAccessToTextMemory;
- End;
-
- Procedure ClearSecondFontMemory;
- Var Counter : Word;
- Begin
- SetAccessToFontMemory;
-
- For Counter := 0 to 32 * 256 do
- MEM[$B800:$4000 + Counter] := 0;
-
- SetAccessToTextMemory;
- End;
-
- Procedure ScrollMessage;
- Const CharCol : Integer = 8;
- Counter : Byte = 1;
- COUNTERY : Byte = 0;
- PWRTbl : Array [0..7] of Byte = (1,2,4,8,16,32,64,128);
- Begin
- SetAccessToFontMemory;
-
- ASM
- { Wait For Retrace }
- MOV DX, $3DA
- @RT:
- IN AL, DX
- TEST AL, 8
- JZ @RT
-
- { Scroll Text One Pixel To The Left }
- MOV AX, $B800 + ($4000 / 16)
- MOV ES, AX
- MOV CX, 32
- @Row:
- MOV DI, (79 * 32) - 1
- ADD DI, CX
- SHL byte ptr ES:[DI], 1
- PUSHF
- SUB DI, 32
- POPF
- PUSH CX
- MOV CX, 79
- @Chrs:
- RCL byte ptr ES:[DI], 1
- PUSHF
- SUB DI, 32
- POPF
- Loop @Chrs
- POP CX
- Loop @Row
- END;
-
- If CharCol < 0
- Then
-
- Begin
- CharCol := 7;
- Inc(Counter);
- End
- Else
- Dec(CharCol);
-
- If Counter > Length(ScrollText)
- Then
- Counter := 1;
-
- { Write New Column Of Pixels }
- For CounterY := 0 to 31 do
- MEM[$B800:$4000 + (79 * 32) + CounterY] :=
- MEM[$B800:$4000 + (79 * 32) + CounterY] OR
- ((FontDef[Ord(ScrollText[Counter]), CounterY] AND PwrTbl[CharCol])
- SHR CharCol);
-
- SetAccessToTextMemory;
- End;
-
- Procedure TurnCursorOff; Assembler;
- ASM
- MOV DX, $3D4
- MOV AL, $0A
- OUT DX, AL
- MOV DX, $3D5
- IN AL, DX
- OR AL, 32
- OUT DX, AL
- End;
-
- Procedure TurnCursorOn; Assembler;
- ASM
- MOV DX, $3D4
- MOV AL, $0A
- OUT DX, AL
- MOV DX, $3D5
- IN AL, DX
- AND AL, Not(32)
- OUT DX, AL
- End;
-
- Begin
- TextMode (C80);
- TurnCursorOff;
- SetCharWidthTo8;
- MakeFontDefTable;
- ClearSecondFontMemory;
- TextColor(Red);
- ClrScr;
-
- ScrollText := 'This program is one example of how a smooth '+
- 'scroll can be done in text mode. ';
-
- WriteScrollTextCharacters(10);
-
- TextColor(Blue);
- GoToXY (26,10);
- Write ('Text Mode Smooth Scroll Example');
- GoToXY (34,11);
- Write ('By David Dahl');
-
- FlushKeyBoardBuffer;
-
- Repeat
- ScrollMessage;
- Until Keypressed;
-
- FlushKeyboardBuffer;
-
- TextMode (C80);
- TurnCursorOn;
- End.